/*
 * REFTimer.h
 *
 *  Created on: Jun 12, 2013
 *      Author: Lucifer
 */

#ifndef REFTIMER_H_
#define REFTIMER_H_

namespace BFX
{

class REFTimerService;
class REFTimerContext;

typedef	REFWrapper<Queue<REF<REFTimerContext> > >	REFTimerContextQueue;

/**
 * Represents the method that handles calls from a BFX::REFTimer.
 */
typedef	Delegate<void (void)>	TimerCallback;

/**
 * Provides a mechanism for executing one or more method(s) at specified time.
 */
class REFTimer : public REFObject
{
public:
	/**
	 * Initializes a new instance of the BFX::REFTimer with given dispatcher.
	 * @param pDispatcher The event dispatcher.
	 */
	REFTimer(REFEventDispatcher* pDispatcher);
	/**
	 * Initializes a new instance of the BFX::REFTimer with given absolute expiration, dispatcher.
	 * @param absoluteExpiration The absolute expiration.
	 * @param pDispatcher the event dispatcher.
	 */
	REFTimer(const Time& absoluteExpiration, REFEventDispatcher* pDispatcher);

	/**
	 * Initializes a new instance of the BFX::REFTimer with given sliding expiration, dispatcher.
	 * @param slidingExpiration The sliding expiration.
	 * @param pDispatcher The event dispatcher.
	 */
	REFTimer(const TimeSpan& slidingExpiration, REFEventDispatcher* pDispatcher);

	/**
	 * Destructor to destroys the BFX::REFTimer instance.
	 */
	virtual ~REFTimer();

	/**
	 * Gets the timer's absolute expiration time.
	 * @return
	 */
	Time GetAbsoluteExpiration() const;
	/**
	 * Sets the timer's absolute expiration time.
	 * @param absoluteExpiration
	 */
	void SetAbsoluteExpiration(const Time& absoluteExpiration);

	/**
	 * Gets the timer's sliding expiration time from now.
	 * @return
	 */
	TimeSpan GetSlidingExpiration() const;
	/**
	 * Sets the timer's sliding expiration time from now.
	 * @param slidingExpiration
	 */
	void SetSlidingExpiration(const TimeSpan& slidingExpiration);

	/**
	 * Performs a blocking wait on the timer.
	 */
	void Wait();

	/**
	 * Starts an asynchronous wait on the timer.
	 * @param callback
	 */
	void WaitAsync(TimerCallback callback);

	/**
	 * Cancel any asynchronous operations that are waiting on the timer.
	 * @return The number of asynchronous operations that were canceled.
	 */
	int Cancel();

private:
	void Initialize(const Time& absoluteExpiration, REFEventDispatcher* pDispatcher);

private:
	friend class REFTimerService;
	friend class REFTimerQueue;

	REF<REFTimerService>	m_pTimerService;
	Time	m_absoluteExpiration;
	REF<REFTimerContextQueue>	m_pContextQueue;

	//
	// NOTE: the following attributes uses by BFX::REFTimerQueue only.
	// The BFX::REFTimerQueue be allowed to direct access the following attributes to improve performance.
	//
	int			m_nSortIndex;
	REFTimer*	m_pPrev;
	REFTimer*	m_pNext;
};

} /* namespace BFX */

#endif /* REFTIMER_H_ */
